package forum.client.controllerlayer;

import java.awt.Component;
import java.io.IOException;
import java.util.Date;
import java.util.logging.Logger;
import forum.Settings;
import forum.client.exceptions.CommunicationException;
import forum.client.ui.ForumTree;
import forum.client.ui.UserType;
import forum.client.ui.events.*;
import forum.server.domain.Gender;
import forum.server.domain.PostContent;
import forum.communication.*;

/**
 * You need to delete all the code in here and implement it yourself.<br>
 * This code is just for you to understand how to work with the
 * Observer/Observed and GUI.
 *
 * @author Tomer Heber
 */
public class ControllerHandlerImpl extends ControllerHandler {

        private String loggedInUser;
	private ClientConnectionController connHandler;
	private static Logger log = Logger.getLogger(Settings.loggerName);


	public ControllerHandlerImpl() {
        try {
            this.connHandler = new ClientConnectionController("127.0.0.1",
                    (short)1234);
        } catch (IOException ex) {
            log.severe(ex.getMessage());
        }

        this.loggedInUser = "Guest";
	}

	/* (non-Javadoc)
	 * @see forumtree.contol.ControllerHandler#getForumView()
	 */
	@Override
	public synchronized String[] getForumView() {
		ServerResponse response;
                String[] result = new String[2];
		try {
			response = this.connHandler.sendMsg(new ViewForumMessage());
			if (response.hasExecuted()){
                                result[0] = "succ";
				result[1] = response.getResponse();
                        }
			else{
                                result[0] = "fail";
				result[1] = response.getResponse();
				//notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                        }
		} catch (CommunicationException e) {
                        result[0] = "comm";
                        result[1] = "Communication error.";
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
		}
		return result;
	}

        public synchronized String[] getOneSearchView(int postID){
            ServerResponse response;
            String[] result = new String[2];
		try {
			response = this.connHandler.sendMsg(new SearchResultView(postID));
			if (response.hasExecuted()){
				//return response.getResponse();
                                result[0] = "succ";
				result[1] = response.getResponse();
                        }
			else{
				//notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                                result[0] = "fail";
				result[1] = response.getResponse();
                        }
		} catch (CommunicationException e) {
                        result[0] = "comm";
                        result[1] = "Communication error.";
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
		}
		return result;
        }

	@Override
	public synchronized String[] modifyMessage(long id, String newContent, Component comp) {
		ServerResponse response;
                String[] result = new String[2];
		try {
			response = this.connHandler.sendMsg(new ModifyMessageMessage
					((int)id, new PostContent(newContent)));
			if (response.hasExecuted()){
				//notifyObservers(new ForumTreeRefreshEvent(comp,getForumView()));
                                result[0] = "succ";
                        }
			else{
				//notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                                result[0] = "fail";
				result[1] = response.getResponse();
                        }

		} catch (CommunicationException e) {
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
                        result[0] = "comm";
                        result[1] = "Communication error.";
		}
                return result;
	}

	@Override
	public synchronized String[] addReplyToMessage(long id, String string, Component comp) {
		ServerResponse response;
                String[] result = new String[2];
		try {
			response = this.connHandler.sendMsg(new AddReplyMessage(
					(int)id, "", new PostContent(string)));
			if (response.hasExecuted()){
				//notifyObservers(new ForumTreeRefreshEvent(comp,getForumView()));
                                result[0] = "succ";
            } else{
				//notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                                result[0] = "fail";
				result[1] = response.getResponse();
            }
		} catch (CommunicationException e) {
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
                        result[0] = "comm";
                        result[1] = "Communication error.";
		}
           return result;
	}

	@Override
	public synchronized String[] deleteMessage(long id, Component comp) {
        ServerResponse response;
        String[] result = new String[2];
		try {
			response = this.connHandler.sendMsg(new DeleteMessageMessage((int)id));
			if (response.hasExecuted()){
				 result[0] = "succ";
            } else{
				//notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                            result[0] = "fail";
                            result[1] = response.getResponse();
            }
		} catch (CommunicationException e) {
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
                        result[0] = "comm";
                        result[1] = "Communication error.";
		}
        return result;
	}

	@Override
	public synchronized String[] addNewMessage(String header, String body,Component comp) {
		ServerResponse response;
                String[] result = new String[2];
		try {
            
                        PostContent content = new PostContent(body);
			response = this.connHandler.sendMsg(new AddMessageMessage(header, content));
			if (response.hasExecuted()){
                 //System.out.println("Adding message succeded");
                 //System.out.println(response.getResponse());
		//		notifyObservers(new ForumTreeRefreshEvent(comp,getForumView()));
                            result[0] = "succ";
            } else{
                 //System.out.println("Adding message failed");
                 //System.out.println(response.getResponse());
				//notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                            result[0] = "fail";
                            result[1] = response.getResponse();

            }
		} catch (CommunicationException e) {
			//e.printStackTrace();
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
                        result[0] = "comm";
                        result[1] = "Communication error.";
		}
               return result;
	}

	@Override
	public synchronized String[] getUsersToDemote() {
		ServerResponse response;
		try {
			response = this.connHandler.sendMsg(new GetModeratorsMessage());
			if (response.hasExecuted())
				return response.getResponse().split(",");
			else
				notifyObservers(new UsersListErrorEvent(response.getResponse()));
		} catch (CommunicationException e) {
			notifyObservers(new UsersListErrorEvent("Communication error."));
		}
		return null;
	}

	@Override
	public synchronized String[] getUsersToPromote() {
		ServerResponse response;
		try {
			response = this.connHandler.sendMsg(new GetUsersForPromotionMessage());
			if (response.hasExecuted())
				return response.getResponse().split(",");
			else
				notifyObservers(new UsersListErrorEvent(response.getResponse()));
		} catch (CommunicationException e) {
			notifyObservers(new UsersListErrorEvent("Communication error."));
		}
		return null;
	}

	@Override
	public synchronized String[] getAllUsers() {
		ServerResponse response;
		try {
			response = this.connHandler.sendMsg(new GetAllUsersMessage());
			if (response.hasExecuted())
				return response.getResponse().split(",");
			else
				notifyObservers(new UsersListErrorEvent(response.getResponse()));
		} catch (CommunicationException e) {
			notifyObservers(new UsersListErrorEvent("Communication error."));
		}
		return null;
	}

	@Override
	public synchronized void demoteUsers(String[] users) {
		ServerResponse response;
		try{
			response=this.connHandler.sendMsg(new DemoteModeratorMessage(users));
			if (response.hasExecuted()) return;
			else notifyObservers(new UsersListErrorEvent(response.getResponse()));
		}
		catch (CommunicationException e) {
			notifyObservers(new UsersListErrorEvent("Communication error."));
		}

	}

	@Override
	public synchronized void promoteUsers(String[] users) {
		ServerResponse response;
		try{
			response=this.connHandler.sendMsg(new PromoteModeratorMessage(users));
			if (response.hasExecuted()) return;
			else notifyObservers(new UsersListErrorEvent(response.getResponse()));
		}
		catch (CommunicationException e) {
			notifyObservers(new UsersListErrorEvent("Communication error."));
		}
	}
	
	@Override
	public synchronized String[] login(Component comp, String user, String pass) {
		ServerResponse response;
        this.loggedInUser = user;
        String[] result =new String[2];

		try {
			response = this.connHandler.sendMsg(new LoginMessage(user,pass));
			if (response.hasExecuted()) {
                //System.out.println(response.getResponse());
                int lastIndex=response.getResponse().length(); 
                String permission=response.getResponse().substring(lastIndex-1);
                int per=Integer.parseInt(permission);
                ForumTree.userName = user;
                switch(per){
                case 1:
                	ForumTree.userType = UserType.LOGGEDINUSER;
                	break;
                case 2:
                	ForumTree.userType = UserType.MODERATOR;
                	break;
                case 3:
                	ForumTree.userType = UserType.ADMIN;
                	break;
                default:
                	ForumTree.userType = UserType.GUEST;
                    this.loggedInUser = "Guest";
                	break;
                }
                //notifyObservers(new ForumTreeRefreshEvent(comp,getForumView()));
                //return true;
                result[0] = "succ";
				//return response.getResponse();
            } else {
                //System.out.println(response.getResponse());
                this.loggedInUser = "Guest";
                //notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                result[0] = "fail";
                result[1] = response.getResponse();
            }
		} catch (CommunicationException e) {
            this.loggedInUser = "Guest";
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
                        result[0] = "comm";
                        result[1] = "Communication error.";
		}
        return result;
	}

	@Override
	public synchronized String[] logoff(boolean exitStatus) {
		ServerResponse response;
                String[] result = new String[2];
		try {
                    response = this.connHandler.sendMsg(new LogoffMessage(exitStatus));
                    if (response.hasExecuted()) {
                        //System.out.println(response.getResponse());
                        ForumTree.userType = UserType.GUEST;
                        this.loggedInUser = "Guest";
                        //notifyObservers(new ForumTreeRefreshEvent(comp,getForumView()));
				//return response.getResponse();
                        result[0] = "succ";
            } else {
                //System.out.println(response.getResponse());
                //notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                 result[0] = "fail";
                result[1] = response.getResponse();
            }
		} catch (CommunicationException e) {
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
                    result[0] = "comm";
                    result[1] = "Communication error.";
		}
                return result;
	}

    @Override
    public synchronized String[] register(Component comp, String username, String password, String firstName, String lastName, String email, Gender gender, String city, Date birthday) {
        ServerResponse response;
        String[] result = new String[2];
		try {
			response = this.connHandler.sendMsg(new RegisterMessage(username,password,firstName,lastName,email,gender,city,birthday));
			if (response.hasExecuted()) {
                //System.out.println(response.getResponse());
               // notifyObservers(new ForumTreeRefreshEvent(comp,getForumView()));
                            result[0] = "succ";
                } else {
                    //System.out.println(response.getResponse());
                    //notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                    result[0] = "fail";
                    result[1] = response.getResponse();
                }
		} catch (CommunicationException e) {
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
                    result[0] = "comm";
                    result[1] = "Communication error.";
		}
        return result;
    }

	@Override
	public synchronized String[] searchByAuthor(String username, int from, int to, Component comp) {
        ServerResponse response;
        String[] result = new String[2];
		try {
			response = this.connHandler.sendMsg(new SearchByAuthorMessage(username, from, to));
			if (response.hasExecuted()) {
                //System.out.println(response.getResponse());
                //notifyObservers(new ForumTreeRefreshEvent(comp, response.getResponse()));
                            result[0] = "succ";
                            result[1] = response.getResponse();
            } else {
                //System.out.println(response.getResponse());
                //notifyObservers(new ForumTreeErrorEvent(response.getResponse(), comp));
                            result[0] = "fail";
                            result[1] = response.getResponse();
            }
            
		} catch (CommunicationException e) {
			//notifyObservers(new ForumTreeErrorEvent("Communication error.", comp));
                    result[0] = "comm";
                    result[1] = "Communication error.";
		}
        return result;
	}

	@Override
	public synchronized String[] searchByContent(String content, int from, int to, Component comp) {
            ServerResponse response;
            String[] result = new String[2];
		try {
			response = this.connHandler.sendMsg(new SearchByContentMessage(content, from, to));
			if (response.hasExecuted()) {
                //System.out.println(response.getResponse());
                //notifyObservers(new ForumTreeRefreshEvent(comp, response.getResponse()));
                            result[0] = "succ";
                            result[1] = response.getResponse();
            } else {
                //System.out.println(response.getResponse());
                //notifyObservers(new ForumTreeErrorEvent(response.getResponse()));
                             result[0] = "fail";
                            result[1] = response.getResponse();
            }
		} catch (CommunicationException e) {
			//notifyObservers(new ForumTreeErrorEvent("Communication error."));
                        result[0] = "comm";
                        result[1] = "Communication error.";
		}
            return result;
	}

	@Override
	public synchronized String[] getConnectedUsers() {
		ServerResponse response;
                String[] result = new String[2];
		try {
			response = this.connHandler.sendMsg(new GetConnectedUsersMessage());
			if (response.hasExecuted()){
				//return response.getResponse();
                                result[0] = "succ";
                            result[1] = response.getResponse();
                        }
			else{
				//return "Failed to execute.";
                            result[0] = "fail";
                            result[1] = "Failed to execute get connected users.";
                        }
		} catch (CommunicationException e) {
			//return "Failed to execute.";
                    result[0] = "comm";
                    result[1] = "Communication error.";
		}
                return result;
	}

    @Override
    public synchronized String getLoggedInUser() {
        return this.loggedInUser;
    }

}
